home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / cave.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  13KB  |  492 lines

  1. /***************************************************************************
  2.  
  3.                               -= Cave Games =-
  4.  
  5.                 driver by    Luca Elia (eliavit@unina.it)
  6.  
  7.  
  8. Note:    if MAME_DEBUG is defined, pressing:
  9.  
  10.         X/C/V/B/Z  with  Q   shows layer 0 (tiles with priority 0/1/2/3/All)
  11.         X/C/V/B/Z  with  W   shows layer 1 (tiles with priority 0/1/2/3/All)
  12.         X/C/V/B/Z  with  E   shows layer 2 (tiles with priority 0/1/2/3/All)
  13.         X/C/V/B/Z  with  A   shows sprites (tiles with priority 0/1/2/3/All)
  14.  
  15.         Keys can be used togheter!
  16.  
  17.         [ 1, 2 or 3 Scrolling Layers ]
  18.  
  19.         Layer Size:                512 x 512
  20.         Tiles:                    16x16x8 (16x16x4 in some games)
  21.  
  22.         [ 1024 Zooming Sprites ]
  23.  
  24.         There are 2 spriterams. A hardware register's bit selects
  25.         the one to display (sprites double buffering)
  26.  
  27.  
  28. **************************************************************************/
  29. #include "vidhrdw/generic.h"
  30.  
  31.  
  32. /* Variables that driver has access to: */
  33. unsigned char *cave_videoregs;
  34.  
  35. unsigned char *cave_vram_0, *cave_vctrl_0;
  36. unsigned char *cave_vram_1, *cave_vctrl_1;
  37. unsigned char *cave_vram_2, *cave_vctrl_2;
  38.  
  39. unsigned char *cave_soundram;
  40.  
  41.  
  42. /* Variables only used here: */
  43.  
  44. static struct sprite_list *sprite_list;
  45. static struct tilemap *tilemap_0, *tilemap_1, *tilemap_2;
  46.  
  47.  
  48.  
  49.  
  50. WRITE_HANDLER( cave_soundram_w )
  51. {
  52.     int oldword, newword;
  53.  
  54.     oldword = READ_WORD(&cave_soundram[offset]);
  55.     COMBINE_WORD_MEM(&cave_soundram[offset], data);
  56.     newword = READ_WORD(&cave_soundram[offset]);
  57. #if 0
  58.     if (newword != oldword)
  59.     {
  60.         char buf[80];
  61.         sprintf(buf,"%04X %04X",READ_WORD(&cave_soundram[0]),READ_WORD(&cave_soundram[2]));
  62.         usrintf_showmessage(buf);
  63.     }
  64. #endif
  65. }
  66.  
  67.  
  68.  
  69.  
  70. /***************************************************************************
  71.  
  72.                         Callbacks for the TileMap code
  73.  
  74.                               [ Tiles Format ]
  75.  
  76. Offset:
  77.  
  78. 0.w            fe-- ---- ---- ---        Priority
  79.             --dc ba98 ---- ----        Color
  80.             ---- ---- 7654 3210
  81.  
  82. 2.w                                    Code
  83.  
  84.  
  85.  
  86. ***************************************************************************/
  87.  
  88. #define DIM_NX        (0x20)
  89. #define DIM_NY        (0x20)
  90.  
  91.  
  92. #define CAVE_TILEMAP(_n_) \
  93. static void get_tile_info_##_n_( int tile_index ) \
  94. { \
  95.     int code        =    (READ_WORD(&cave_vram_##_n_[ tile_index * 4 + 0]) << 16 )+ \
  96.                          READ_WORD(&cave_vram_##_n_[ tile_index * 4 + 2]); \
  97.     SET_TILE_INFO( _n_ ,  code & 0x00ffffff , (code & 0x3f000000) >> (32-8) ); \
  98.     tile_info.priority = (code & 0xc0000000)>> (32-2); \
  99. } \
  100. \
  101. WRITE_HANDLER( cave_vram_##_n_##_w ) \
  102. { \
  103.     COMBINE_WORD_MEM(&cave_vram_##_n_[offset],data); \
  104.     if ( (offset/4) < DIM_NX * DIM_NY ) \
  105.         tilemap_mark_tile_dirty(tilemap_##_n_, offset/4 ); \
  106. }
  107.  
  108. CAVE_TILEMAP(0)
  109. CAVE_TILEMAP(1)
  110. CAVE_TILEMAP(2)
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119. /* 3 Layers */
  120. int esprade_vh_start(void)
  121. {
  122.     tilemap_0 = tilemap_create(    get_tile_info_0,
  123.                                 tilemap_scan_rows,
  124.                                 TILEMAP_TRANSPARENT,
  125.                                 16,16,
  126.                                 DIM_NX,DIM_NY );
  127.  
  128.     tilemap_1 = tilemap_create(    get_tile_info_1,
  129.                                 tilemap_scan_rows,
  130.                                 TILEMAP_TRANSPARENT,
  131.                                 16,16,
  132.                                 DIM_NX,DIM_NY );
  133.  
  134.     tilemap_2 = tilemap_create(    get_tile_info_2,
  135.                                 tilemap_scan_rows,
  136.                                 TILEMAP_TRANSPARENT,
  137.                                 16,16,
  138.                                 DIM_NX,DIM_NY );
  139.  
  140.  
  141.     sprite_list = sprite_list_create(spriteram_size / 0x10 / 2, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
  142.  
  143.     if (tilemap_0 && tilemap_1 && tilemap_2 && sprite_list)
  144.     {
  145.         tilemap_set_scroll_rows(tilemap_0,1);
  146.         tilemap_set_scroll_cols(tilemap_0,1);
  147.         tilemap_0->transparent_pen = 0;
  148.  
  149.         tilemap_set_scroll_rows(tilemap_1,1);
  150.         tilemap_set_scroll_cols(tilemap_1,1);
  151.         tilemap_1->transparent_pen = 0;
  152.  
  153.         tilemap_set_scroll_rows(tilemap_2,1);
  154.         tilemap_set_scroll_cols(tilemap_2,1);
  155.         tilemap_2->transparent_pen = 0;
  156.  
  157.         tilemap_set_scrolldx( tilemap_0, -0x6c, -0x57 );
  158.         tilemap_set_scrolldx( tilemap_1, -0x6d, -0x56 );
  159.         tilemap_set_scrolldx( tilemap_2, -0x6e, -0x55 );
  160.  
  161.         tilemap_set_scrolldy( tilemap_0, -0x11, -0x100 );
  162.         tilemap_set_scrolldy( tilemap_1, -0x11, -0x100 );
  163.         tilemap_set_scrolldy( tilemap_2, -0x11, -0x100 );
  164.  
  165.         sprite_list->max_priority = 3;
  166.         sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
  167.  
  168.         return 0;
  169.     }
  170.     else return 1;
  171. }
  172.  
  173.  
  174.  
  175. /* 2 Layers */
  176. int dfeveron_vh_start(void)
  177. {
  178.     tilemap_0 = tilemap_create(    get_tile_info_0,
  179.                                 tilemap_scan_rows,
  180.                                 TILEMAP_TRANSPARENT,
  181.                                 16,16,
  182.                                 DIM_NX,DIM_NY );
  183.  
  184.     tilemap_1 = tilemap_create(    get_tile_info_1,
  185.                                 tilemap_scan_rows,
  186.                                 TILEMAP_TRANSPARENT,
  187.                                 16,16,
  188.                                 DIM_NX,DIM_NY );
  189.  
  190.     tilemap_2 = 0;
  191.  
  192.     sprite_list = sprite_list_create(spriteram_size / 0x10 / 2, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
  193.  
  194.     if (tilemap_0 && tilemap_1 && sprite_list)
  195.     {
  196.         tilemap_set_scroll_rows(tilemap_0,1);
  197.         tilemap_set_scroll_cols(tilemap_0,1);
  198.         tilemap_0->transparent_pen = 0;
  199.  
  200.         tilemap_set_scroll_rows(tilemap_1,1);
  201.         tilemap_set_scroll_cols(tilemap_1,1);
  202.         tilemap_1->transparent_pen = 0;
  203.  
  204. /*
  205.     Scroll registers (on dfeveron logo screen):
  206.         8195    a1f7 (both)    =    200-6b    200-9    (flip off)
  207.         01ac    2108 (both)    =    200-54    100+8    (flip on)
  208.     Video registers:
  209.         0183    0001        =    200-7d    001        (flip off)
  210.         81bf    80f0        =    200-41    100-10    (flip on)
  211. */
  212.  
  213.         tilemap_set_scrolldx( tilemap_0, -0x6c, -0x54 );
  214.         tilemap_set_scrolldx( tilemap_1, -0x6d, -0x53 );
  215.  
  216.         tilemap_set_scrolldy( tilemap_0, -0x11, -0x100 );
  217.         tilemap_set_scrolldy( tilemap_1, -0x11, -0x100 );
  218.  
  219.         sprite_list->max_priority = 3;
  220.         sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
  221.  
  222.         return 0;
  223.     }
  224.     else return 1;
  225. }
  226.  
  227.  
  228.  
  229.  
  230.  
  231. /* 1 Layer */
  232. int uopoko_vh_start(void)
  233. {
  234.     tilemap_0 = tilemap_create(    get_tile_info_0,
  235.                                 tilemap_scan_rows,
  236.                                 TILEMAP_TRANSPARENT,
  237.                                 16,16,
  238.                                 DIM_NX,DIM_NY );
  239.  
  240.     tilemap_1 = 0;
  241.  
  242.     tilemap_2 = 0;
  243.  
  244.     sprite_list = sprite_list_create(spriteram_size / 0x10 / 2, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
  245.  
  246.     if (tilemap_0 && sprite_list)
  247.     {
  248.         tilemap_set_scroll_rows(tilemap_0,1);
  249.         tilemap_set_scroll_cols(tilemap_0,1);
  250.         tilemap_0->transparent_pen = 0;
  251.  
  252.         tilemap_set_scrolldx( tilemap_0, -0x6d, -0x54 );
  253.  
  254.         tilemap_set_scrolldy( tilemap_0, -0x11, -0x100 );
  255.  
  256.         sprite_list->max_priority = 3;
  257.         sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
  258.  
  259.         return 0;
  260.     }
  261.     else return 1;
  262. }
  263.  
  264.  
  265.  
  266.  
  267. /* 4 bit sprites here, rather than 8 bit */
  268. void dfeveron_vh_init_palette(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  269. {
  270.     int color, pen;
  271.  
  272.     /* Fill the 0-3fff range, used by sprites ($40 color codes * $100 pens)
  273.        Here sprites have 16 pens, but the sprite drawing routine always
  274.        multiplies the color code by $100 (for consistency).
  275.        That's why we need this function.    */
  276.  
  277.     for( color = 0; color < 0x40; color++ )
  278.         for( pen = 0; pen < 16; pen++ )
  279.             colortable[color * 256 + pen] = color * 16 + pen;
  280. }
  281.  
  282.  
  283.  
  284. /* --------------------------[ Sprites Format ]----------------------------
  285.  
  286. Offset:        Format:                    Value:
  287.  
  288. 00.w        fedc ba98 76-- ----        X Position
  289.             ---- ---- --54 3210
  290.  
  291. 02.w        fedc ba98 76-- ----        Y Position
  292.             ---- ---- --54 3210
  293.  
  294. 04.w        fe-- ---- ---- ----
  295.             --dc ba98 ---- ----        Color
  296.             ---- ---- 76-- ----
  297.             ---- ---- --54 ----        Priority
  298.             ---- ---- ---- 3---        Flip X
  299.             ---- ---- ---- -2--        Flip Y
  300.             ---- ---- ---- --10        Unused?
  301.  
  302. 06.w                                Code
  303.  
  304. 08/0A.w                                Zoom X / Y
  305.  
  306. 0C.w        fedc ba98 ---- ----        Tile Size X
  307.             ---- ---- 7654 3210        Tile Size Y
  308.  
  309. 0E.w                                Unused
  310.  
  311. ------------------------------------------------------------------------ */
  312.  
  313. static void get_sprite_info(void)
  314. {
  315.     const int region                =    REGION_GFX4;
  316.  
  317.     const unsigned short *base_pal    =    Machine->remapped_colortable + 0;
  318.     const unsigned char  *base_gfx    =    memory_region(region);
  319.     const unsigned char  *gfx_max    =    base_gfx + memory_region_length(region);
  320.  
  321.     int sprite_bank                    =    READ_WORD(&cave_videoregs[8]) & 1;
  322.  
  323.     unsigned char *source            =    spriteram + (spriteram_size / 2) * sprite_bank;
  324.     struct sprite *sprite            =    sprite_list->sprite;
  325.     const struct sprite *finish        =    sprite + spriteram_size / 0x10 / 2;
  326.  
  327.     int    glob_flipx    =    READ_WORD(&cave_videoregs[0]) & 0x8000;
  328.     int    glob_flipy    =    READ_WORD(&cave_videoregs[2]) & 0x8000;
  329.  
  330.     int max_x        =    Machine->drv->screen_width;
  331.     int max_y        =    Machine->drv->screen_height;
  332.  
  333.     for (; sprite < finish; sprite++,source+=0x10 )
  334.     {
  335.         int    x            =        READ_WORD(&source[ 0x00 ]);
  336.         int    y            =        READ_WORD(&source[ 0x02 ]);
  337.         int    attr        =        READ_WORD(&source[ 0x04 ]);
  338.         int    code        =        READ_WORD(&source[ 0x06 ]);
  339.         int    zoomx        =        READ_WORD(&source[ 0x08 ]);
  340.         int    zoomy        =        READ_WORD(&source[ 0x0a ]);
  341.         int    size        =        READ_WORD(&source[ 0x0c ]);
  342.  
  343.         int    flipx        =        attr & 0x0008;
  344.         int    flipy        =        attr & 0x0004;
  345.  
  346.         if (x & 0x8000)    x -= 0x10000;
  347.         if (y & 0x8000)    y -= 0x10000;
  348.  
  349.         x /= 0x40;        y /= 0x40;
  350.  
  351.         sprite->priority        =    (attr & 0x0030) >> 4;
  352.         sprite->flags            =    SPRITE_VISIBLE;
  353.  
  354.         sprite->tile_width        =    ( (size >> 8) & 0x0f ) * 16;
  355.         sprite->tile_height        =    ( (size >> 0) & 0x0f ) * 16;
  356.  
  357.         sprite->total_width        =    (sprite->tile_width  * zoomx) / 0x100;
  358.         sprite->total_height    =    (sprite->tile_height * zoomy) / 0x100;
  359.  
  360.         sprite->pen_data        =    base_gfx + (16*16) * code;
  361.         sprite->line_offset        =    sprite->tile_width;
  362.  
  363.         sprite->pal_data        =    base_pal + (attr & 0x3f00);    // first 0x4000 colors
  364.  
  365.         /* Bound checking */
  366.         if ((sprite->pen_data + sprite->tile_width * sprite->tile_height - 1) >= gfx_max )
  367.             {sprite->flags = 0;    continue;}
  368.  
  369.         if (glob_flipx)    { x = max_x - x - sprite->total_width;    flipx = !flipx; }
  370.         if (glob_flipy)    { y = max_y - y - sprite->total_height;    flipy = !flipy; }
  371.  
  372.         sprite->x                =    x;
  373.         sprite->y                =    y;
  374.  
  375.         if (flipx)    sprite->flags |= SPRITE_FLIPX;
  376.         if (flipy)    sprite->flags |= SPRITE_FLIPY;
  377.  
  378.  
  379. #if 0
  380.  
  381. #ifdef MAME_DEBUG
  382.         if ( keyboard_pressed(KEYCODE_Z) && keyboard_pressed(KEYCODE_N) )
  383.         {
  384.             struct DisplayText dt[3];
  385.             char buf1[40],buf2[40];
  386.  
  387.             if ( (zoomx == 0x100) && (zoomy == 0x100) )    continue;
  388.  
  389.             dt[0].text = buf1;        dt[1].text = buf2;    dt[2].text = 0;
  390.             dt[0].color            =    dt[1].color = UI_COLOR_NORMAL;
  391.             dt[0].x = y;            dt[1].x = dt[0].x;
  392.             dt[0].y = max_x-x;        dt[1].y = dt[0].y + 8;
  393.  
  394.             sprintf(buf1, "1:%04X", zoomx);
  395.             sprintf(buf2, "2:%04X", zoomy);
  396.             displaytext(dt,0,0);
  397.         }
  398. #endif
  399.  
  400. #endif
  401.  
  402.     }
  403. }
  404.  
  405.  
  406.  
  407. void cave_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  408. {
  409.     int pri;
  410.     int layers_ctrl = -1;
  411.  
  412.     int    glob_flipx    =    READ_WORD(&cave_videoregs[0]) & 0x8000;
  413.     int    glob_flipy    =    READ_WORD(&cave_videoregs[2]) & 0x8000;
  414.  
  415.     tilemap_set_flip(ALL_TILEMAPS, (glob_flipx ? TILEMAP_FLIPX : 0) | (glob_flipy ? TILEMAP_FLIPY : 0) );
  416.  
  417.     tilemap_set_enable( tilemap_0, READ_WORD(&cave_vctrl_0[4]) & 1 );
  418.     tilemap_set_scrollx(tilemap_0, 0, READ_WORD(&cave_vctrl_0[0]) );
  419.     tilemap_set_scrolly(tilemap_0, 0, READ_WORD(&cave_vctrl_0[2]) );
  420.  
  421.     if (tilemap_1)
  422.     {
  423.         tilemap_set_enable( tilemap_1, READ_WORD(&cave_vctrl_1[4]) & 1 );
  424.         tilemap_set_scrollx(tilemap_1, 0, READ_WORD(&cave_vctrl_1[0]) );
  425.         tilemap_set_scrolly(tilemap_1, 0, READ_WORD(&cave_vctrl_1[2]) );
  426.     }
  427.  
  428.     if (tilemap_2)
  429.     {
  430.         tilemap_set_enable( tilemap_2, READ_WORD(&cave_vctrl_2[4]) & 1 );
  431.         tilemap_set_scrollx(tilemap_2, 0, READ_WORD(&cave_vctrl_2[0]) );
  432.         tilemap_set_scrolly(tilemap_2, 0, READ_WORD(&cave_vctrl_2[2]) );
  433.     }
  434.  
  435.  
  436. #ifdef MAME_DEBUG
  437. if ( keyboard_pressed(KEYCODE_Z) || keyboard_pressed(KEYCODE_X) || keyboard_pressed(KEYCODE_C) ||
  438.      keyboard_pressed(KEYCODE_V) || keyboard_pressed(KEYCODE_B) )
  439. {
  440.     int msk = 0, val = 0;
  441.  
  442.     if (keyboard_pressed(KEYCODE_X))    val = 1;    // priority 0 only
  443.     if (keyboard_pressed(KEYCODE_C))    val = 2;    // ""       1
  444.     if (keyboard_pressed(KEYCODE_V))    val = 4;    // ""       2
  445.     if (keyboard_pressed(KEYCODE_B))    val = 8;    // ""       3
  446.  
  447.     if (keyboard_pressed(KEYCODE_Z))    val = 1|2|4|8;    // All of the above priorities
  448.  
  449.     if (keyboard_pressed(KEYCODE_Q))    msk |= val << 0;    // for layer 0
  450.     if (keyboard_pressed(KEYCODE_W))    msk |= val << 4;    // for layer 1
  451.     if (keyboard_pressed(KEYCODE_E))    msk |= val << 8;    // for layer 2
  452.     if (keyboard_pressed(KEYCODE_A))    msk |= val << 12;    // for sprites
  453.     if (msk != 0) layers_ctrl &= msk;
  454.  
  455. #if 1
  456.     {
  457.         char buf[80];
  458.         sprintf(buf,"%04X %04X %04X %04X %04X %04X %04X %04X",
  459.             READ_WORD(&cave_videoregs[0x0]),READ_WORD(&cave_videoregs[0x2]),
  460.             READ_WORD(&cave_videoregs[0x4]),READ_WORD(&cave_videoregs[0x6]),
  461.             READ_WORD(&cave_videoregs[0x8]),READ_WORD(&cave_videoregs[0xa]),
  462.             READ_WORD(&cave_videoregs[0xc]),READ_WORD(&cave_videoregs[0xe]) );
  463.         usrintf_showmessage(buf);
  464.     }
  465. #endif
  466.  
  467. }
  468. #endif
  469.  
  470.     tilemap_update(ALL_TILEMAPS);
  471.  
  472.     palette_init_used_colors();
  473.  
  474.     get_sprite_info();
  475.  
  476.     sprite_update();
  477.  
  478.     if (palette_recalc())    tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  479.  
  480.     tilemap_render(ALL_TILEMAPS);
  481.  
  482.     osd_clearbitmap(Machine->scrbitmap);
  483.  
  484.     for ( pri = 0; pri < 4; pri++ )
  485.     {
  486.         if ((layers_ctrl&(1<<(pri+12))))            sprite_draw(sprite_list, pri);
  487.         if ((layers_ctrl&(1<<(pri+0)))&&tilemap_0)    tilemap_draw(bitmap, tilemap_0, pri);
  488.         if ((layers_ctrl&(1<<(pri+4)))&&tilemap_1)    tilemap_draw(bitmap, tilemap_1, pri);
  489.         if ((layers_ctrl&(1<<(pri+8)))&&tilemap_2)    tilemap_draw(bitmap, tilemap_2, pri);
  490.     }
  491. }
  492.